package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.zzyl.constant.SuperConstant;
import com.zzyl.dto.ResourceDto;
import com.zzyl.entity.Resource;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.ResourceMapper;
import com.zzyl.service.ResourceService;
import com.zzyl.utils.EmptyUtil;
import com.zzyl.utils.NoProcessing;
import com.zzyl.vo.ResourceVo;
import com.zzyl.vo.TreeItemVo;
import com.zzyl.vo.TreeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ResourceServiceImpl implements ResourceService {
    @Autowired
    private ResourceMapper resourceMapper;

    @Override
    public List<ResourceVo> getList(ResourceDto resourceDto) {
        Resource r = BeanUtil.toBean(resourceDto, Resource.class);
        List<Resource>list =  resourceMapper.list(r);
        return BeanUtil.copyToList(list,ResourceVo.class);
    }

    /**
     * 封装资源的树形结构
     *
     * @param resourceDto
     * @return
     */
    @Override
    public TreeVo resourceTreeVo(ResourceDto resourceDto) {

        //根节点的编号：100001000000000
        //根据根节点的编号，查询出来所有的子孙节点，好处：只查一次数据库
        ResourceDto dto = ResourceDto.builder()
                .parentResourceNo(NoProcessing.processString(SuperConstant.ROOT_PARENT_ID))
                .resourceType(SuperConstant.MENU)
                .dataState(SuperConstant.DATA_STATE_0)
                .build();
        //所有的菜单数据,可以认为，表中的所有数据
        List<Resource> resources = resourceMapper.selectList(dto);
        //最终返回的数据结构
        List<TreeItemVo> itemVos = new ArrayList<>();

        //手动构建一个根节点
        Resource root = new Resource();
        root.setResourceNo(SuperConstant.ROOT_PARENT_ID);
        root.setResourceName("智慧养老院");

        //递归调用封装数据
        recursionTreeItem(itemVos,root,resources);


        return TreeVo.builder().items(itemVos).build();
    }

    /**
     * 递归调用封装数据
     * @param itemVos
     * @param root
     * @param resources  所有的数据
     */
    private void recursionTreeItem(List<TreeItemVo> itemVos, Resource root, List<Resource> resources) {
        //第一次：构建根节点（智慧养老院）
        TreeItemVo treeItemVo = TreeItemVo.builder()
                .id(root.getResourceNo())
                .label(root.getResourceName()).build();
        //找根节点的孩子
        List<Resource> childrenList = resources.stream()
                .filter(n -> n.getParentResourceNo().equals(root.getResourceNo()))
                .collect(Collectors.toList());
        //
        /*List<Resource> new_ = new ArrayList<>();
        for (Resource resource : resources) {
            if(resource.getParentResourceNo().equals(root.getResourceNo())){
                new_.add(resource);
            }
        }*/

        if(!EmptyUtil.isNullOrEmpty(childrenList)){
            //根节点的孩子
            List<TreeItemVo> listChildren = new ArrayList<>();
            childrenList.forEach(resource -> {
                recursionTreeItem(listChildren,resource,resources);
            });
            treeItemVo.setChildren(listChildren);
        }
        itemVos.add(treeItemVo);
    }


    /**
     * 新增菜单
     * @param resourceDto
     */
    @Override
    public void createResource(ResourceDto resourceDto) {
//1、把dto转换为pojo
        Resource resource = BeanUtil.toBean(resourceDto, Resource.class);
//2、根据父资源的no查询父菜单，然后把当前菜单的状态设置为父菜单的状态
        Resource r = new Resource();
        r.setParentResourceNo(resource.getParentResourceNo());
        Resource parent = resourceMapper.selectByParentResourceNo(r.getParentResourceNo());
        if (null == parent){
            throw new BaseException(BasicEnum.PARENT_MENU_NOT_EXIST);
        }
        resource.setDataState(parent.getDataState());
//3、补齐常规字段
        resource.setCreateTime(LocalDateTime.now());
        resource.setUpdateTime(LocalDateTime.now());
        resource.setCreateBy(1671403256519078006L);
        resource.setLabel(resource.getRequestPath().replaceAll("/",","));
        resource.setRemark(resource.getResourceName());
//4、根据父资源的编码生成子资源的编码
        resource.setResourceNo(createResourceNo(resource.getParentResourceNo(),resource.getResourceType()));
//5、新增菜单
        resourceMapper.insert(resource);
    }

    /**
     * 生成子菜单No
     * @param parentResourceNo
     * @param resourceType
     * @return
     */
    private String createResourceNo(String parentResourceNo,String resourceType) {
        if(resourceType != null && resourceType.equals(SuperConstant.MENU)){
            if(NoProcessing.processString(parentResourceNo).length()>12){
                throw new BaseException(BasicEnum.RESOURCE_DEPTH_UPPER_LIMIT);
            }
        }
        Resource resource = new Resource();
        resource.setParentResourceNo(NoProcessing.processString(parentResourceNo));
        List<Resource> list = resourceMapper.list(resource);
        if(list == null || list.size() == 0){
            return NoProcessing.createNo(parentResourceNo,false);
        }else {
            Long maxNo = list.stream().map(r -> Long.parseLong(r.getParentResourceNo())).max(Comparator.comparing(i->i)).get();
            return NoProcessing.createNo(maxNo+"",true);
        }
    }
}